/*
 * SwitchStatus.cpp
 *
 *  Created on: Mar 20, 2012
 *      Author: kylintse
 */

#include <fcntl.h>
#include <sys/ioctl.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "gdata.h"

#include "SwitchStatus.h"
#include "wdg_led.h"

const int led_1000M[]={
		LED_10,
		LED_11,
		LED_12,
};
const int led_100M[]={
		LED_13,
		LED_14,
		LED_15,
		LED_16,
		LED_17,
		LED_18,
		LED_19,
		LED_20,
		LED_21,
		LED_22,
//		LED_23,
//		LED_24,
};

const int hirschman_g_port[]=
{

};

const int hirschman_100m_port[]=
{

};

const int moxa_g_port[]=
{
		8,9,10
};

const int moxa_100m_port[]=
{
		1,2,3,4,5,6,7
};

SwitchStatus::SwitchStatus()
{
	m_switchCheckCount=0;
	m_switchCheckFreq=2;

	if(gswitchType=="Hirschman")
	{
		m_port_g=hirschman_g_port;
		m_port_100m=hirschman_100m_port;
		m_port_g_num=sizeof(hirschman_g_port)/sizeof(int);
		m_port_100m_num=sizeof(hirschman_100m_port)/sizeof(int);
	}
	else if(gswitchType=="Moxa")
	{
		m_port_g=moxa_g_port;
		m_port_100m=moxa_100m_port;
		m_port_g_num=sizeof(moxa_g_port)/sizeof(int);
		m_port_100m_num=sizeof(moxa_100m_port)/sizeof(int);
	}

	m_port_g_status=new int[m_port_g_num];
	m_port_100m_status=new int[m_port_100m_num];
}

SwitchStatus::~SwitchStatus()
{
	// TODO Auto-generated destructor stub
}

void SwitchStatus::run()
{
	QTimer* timerQuery=new QTimer;

	connect(timerQuery,SIGNAL(timeout()),this,SLOT(queryStatus()));

	timerQuery->start(1000);

	exec();

	timerQuery->stop();
	delete timerQuery;
}

void SwitchStatus::queryStatus()
{
//	qWarning()<<"switch status start";
	struct snmp_session session, *ss;
	struct snmp_pdu *pdu;
	struct snmp_pdu *response=NULL;

	oid anOID[MAX_OID_LEN];
	size_t anOID_len = MAX_OID_LEN;

	struct variable_list *vars;
	int status;

	if((m_switchCheckCount++)%m_switchCheckFreq)
		return;

	/*
	* Initialize the SNMP library
	*/
	init_snmp("snmpapp");

	/*
	* Initialize a "session" that defines who we're going to talk to
	*/
	snmp_sess_init( &session );                   /* set up defaults */
	session.peername = gswitchAddr.toAscii().data();

	/* set the SNMP version number */
	session.version = SNMP_VERSION_1;

	/* set the SNMPv1 community name used for authentication */
	session.community = (u_char*)"public";
	session.community_len = strlen((char*)(session.community));

	SOCK_STARTUP;

	/*
	* Open the session
	*/
	ss = snmp_open(&session);                     /* establish the session */

	if (!ss) {
		m_switchCheckFreq=40;
//		setStarted(false);
//		snmp_perror("ack");
//		snmp_log(LOG_ERR, "something horrible happened!!!\n");
		return;
	}

	QString strOid="IF-MIB::ifOperStatus.";
	QString strResult;

	pdu=snmp_pdu_create(SNMP_MSG_GET);

	for(int i=0;i<m_port_g_num;i++)
	{
		anOID_len = MAX_OID_LEN;
		read_objid((strOid+QString::number(m_port_g[i])).toAscii().data(),anOID,&anOID_len);

		snmp_add_null_var(pdu,anOID,anOID_len);
	}

	status=snmp_synch_response(ss,pdu,&response);

	if(status==STAT_SUCCESS&&response->errstat==SNMP_ERR_NOERROR)
	{
		m_switchCheckFreq=2;
		int i;
		for(vars=response->variables,i=0;vars&&i<m_port_g_num;
				vars=vars->next_variable,i++)
		{
			m_port_g_status[i]=*(vars->val.integer);
//				qWarning()<<i<<":"<<port_g_status[i];
			if(m_port_g_status[i]==1)
			{
				::ioctl(m_ledFd,DPR_WDG_TURN_ON_LED,&(led_1000M[i]));
			}
			else
			{
				::ioctl(m_ledFd,DPR_WDG_TURN_OFF_LED,&(led_1000M[i]));
			}
		}
	}
	else
	{
		m_switchCheckFreq=40;
	}

	if(response)
		snmp_free_pdu(response);

//	qWarning()<<"100m_port";
	pdu=snmp_pdu_create(SNMP_MSG_GET);

	for(int i=0;i<m_port_100m_num;i++)
	{
		anOID_len = MAX_OID_LEN;
		read_objid((strOid+QString::number(m_port_100m[i])).toAscii().data(),anOID,&anOID_len);

		snmp_add_null_var(pdu,anOID,anOID_len);
	}

	response=NULL;
	status=snmp_synch_response(ss,pdu,&response);

	if(status==STAT_SUCCESS&&response->errstat==SNMP_ERR_NOERROR)
	{
		m_switchCheckFreq=2;
		int i;
		for(vars=response->variables,i=0;vars&&i<m_port_100m_num;
				vars=vars->next_variable,i++)
		{
			m_port_100m_status[i]=*(vars->val.integer);
//				qWarning()<<i<<":"<<port_100m_status[i];
			if(m_port_100m_status[i]==1)
			{
				::ioctl(m_ledFd,DPR_WDG_TURN_ON_LED,&(led_100M[i]));
			}
			else
			{
				::ioctl(m_ledFd,DPR_WDG_TURN_OFF_LED,&(led_100M[i]));
			}
		}
	}
	else
	{
		m_switchCheckFreq=40;
	}

	if(response)
		snmp_free_pdu(response);

	snmp_close(ss);

	SOCK_CLEANUP;
}

